package com.itheima.reggie.aop;

import com.itheima.reggie.common.BaseContext;
import com.itheima.reggie.common.R;
import com.itheima.reggie.entity.Advice;
import com.itheima.reggie.service.AdviceService;
import lombok.Singular;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.Date;


@Component
@Aspect
@Slf4j
public class AopAdvice {
    @Autowired
    private AdviceService adviceService;
    @Around("@annotation(com.itheima.reggie.aop.Aopannotation)")
    public Object around(ProceedingJoinPoint pjp) throws IOException {
        File file = new File("D://Reggielog/log");
        if (!file.exists()&&!file.isDirectory()){
            file.mkdirs();
        }
        File filePath = new File("D://Reggielog/log/log.txt");
        if(!file.exists()){
            file.createNewFile();
        }
        BufferedWriter fw = new BufferedWriter(new FileWriter(filePath,true));
        //获得执行对象
        Signature signature = pjp.getSignature();
        //获取接口/类全限定名
        String className = signature.getDeclaringTypeName();
        //获取方法名
        String methodName = signature.getName();
        Object object= null;
        try {
            object = pjp.proceed();
        } catch (Throwable throwable) {
            log.error(object.toString());
        }finally{
            //获得目标方法的注解
            Aopannotation a = ((MethodSignature) signature).getMethod().getAnnotation(Aopannotation.class);
            if (object==null){
                log.info("THROWABLE--->>执行者ID:"+BaseContext.getCurrentId()+" TIME:"+LocalDateTime.now()+"-->"+"操作:"+a.type()+"方法为:"+className+methodName);
                Advice advice = new Advice();
                advice.setStatus(0);
                advice.setUserId(BaseContext.getCurrentId());
                advice.setTime(new Date());
                advice.setOperate(a.type());
                advice.setMethod(className+methodName);
                adviceService.save(advice);
                fw.write("THROWABLE--->>执行者ID:"+BaseContext.getCurrentId()+" TIME:"+LocalDateTime.now()+"-->"+"操作:"+a.type()+"方法为:"+className+methodName);
                fw.newLine();
                fw.flush();
                return R.error("请规范操作");
            }
            if (object.toString().contains("code=1")){
                Advice advice = new Advice();
                advice.setStatus(1);
                advice.setUserId(BaseContext.getCurrentId());
                advice.setTime(new Date());
                advice.setOperate(a.type());
                advice.setMethod(className+methodName);
                adviceService.save(advice);
                log.info("SUCCESS--->>执行者ID:"+BaseContext.getCurrentId()+" TIME:"+LocalDateTime.now()+"-->"+"操作:"+a.type()+"方法为:"+className+methodName);
                fw.write("log.info    SUCCESS--->>执行者ID:"+BaseContext.getCurrentId()+" TIME:"+LocalDateTime.now()+"-->"+"操作:"+a.type()+"方法为:"+className+methodName);
                fw.newLine();
                fw.flush();
                return object;
            }
        }
        return object;

    }
}
